﻿//----------------------------------------------------------------
// Desc: 操作系统状态查询器
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2011-05-06
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


#if FUEL_OS_WINDOWS


#define IFSystem_Speciality_Func(_register, _bitset, _func_name)\
    FINLINE bool Is##_func_name()\
    {\
        return ((CPUSpeciality##_register() & (1L<<(_bitset))) != 0);\
    }


class IFSystem : public IFMemObject
{
protected:
    explicit IFSystem()
    {}

public:
    enum enumRefFlags
    {
        eRF_PhysMemSize     = 1<<0, // 刷新物理内存和虚拟内存可用大小
        eRF_VidMemSize      = 1<<1, // 刷新显存可用大小

        eRF_All = 0xFF,
    };

    // 初始化系统硬件和软件状态管理
    // .need_MMX 运行程序必须MMX指令集的支持
    // .need_SSE 运行程序必须SSE指令集的支持
    // .need_phys_mem 最小物理内存要求(单位M) (无要求填0)
    // .need_vid_mem 最小显存要求(单位M) (无要求填0)
    // 注意：如果内部初始化失败会自动抛出提示或打印到文件
    virtual bool Initialize(bool need_MMX, bool need_SSE, INT64 need_phys_mem, INT64 need_vid_mem) = 0;
    // 取CPU速度，此函数是阻塞的
    // .dwTestSecond 阴塞多长时间
    virtual double RefCPUSpeed(DWORD dwTestSecond = 500) = 0;
    // 刷新系统硬件和软件状态
    // .flags: 刷新标记
    virtual void Update(BYTE flags = eRF_All) = 0;
    // 释放系统硬件和软件状态
    virtual void Release() = 0;
    // 获取物理内存的使用率
    virtual float GetPhysMemUsed() = 0;
    // 取得总物理内存大小
    virtual INT64 GetPhysMemSize() = 0;
    // 取当前可用物理内存大小
    virtual INT64 GetPhysMem_CanUsed() = 0;
    // 取得总显存大小
    virtual INT64 GetVidMemSize() = 0;
    // 取得当前显存大小
    virtual INT64 GetVidMem_CanUsed() = 0;
    // 取得当前CPU速度
    virtual double GetCPUSpeed() = 0;
    // 取当前计算机名
    virtual const ACHAR* GetComputer() = 0;
    // 取当前CPU制造商
    virtual const ACHAR* GetCPUVender() = 0;
    // 取当前CPU商标
    virtual const ACHAR* GetCPUBrand() = 0;
    // 取当前CPU数量
    virtual DWORD GetCPUCount() = 0;
    // 取操作系统多语言ID
    virtual WORD GetLanguageID() = 0;

    IFSystem_Speciality_Func(EDX, 23, MMX)              // IsMMX()
    IFSystem_Speciality_Func(EDX, 25, SSE)              // IsSSE()
    IFSystem_Speciality_Func(EDX, 26, SSE2)             // IsSSE2()
    IFSystem_Speciality_Func(EDX, 28, HyperThreading)   // IsHyperThreading()
    IFSystem_Speciality_Func(EDX, 30, IA64)             // IsIA64()

    IFSystem_Speciality_Func(ECX,  0, SSE3)             // IsSSE3()
    IFSystem_Speciality_Func(ECX,  9, SSSE3)            // IsSSSE3()

protected:
    virtual DWORD CPUSpecialityEDX() = 0;
    virtual DWORD CPUSpecialityECX() = 0;
};


extern FAPI IFSystem* FGetSystemQuery();
extern FAPI void FReleaseSystemQuery();


#endif